package f

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha1"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/glog"
	"github.com/gogf/gf/util/gconv"
	uuid "github.com/satori/go.uuid"
	"hash/crc32"
	"time"
)

type Log struct {
	Name string      //日志标题／自定义日志文件分类
	Type string      //类型支持:debug、error、info
	Info interface{} //日志内容
}

//通用日志方法
func (l Log) Com() {
	switch l.Type {
	case "Debug":
		glog.Debug(l.Name, l.Info)
	case "Warning":
		glog.Warningf(l.Name, l.Info)
	case "Error":
		glog.Error(l.Name, l.Info)
	default:
		glog.Info(l.Name, l.Info)
	}
}

//自定义日志方法
func (l Log) Diy() {
	diyLogTypes := []string{"dev-status", "deviceStatus", "times", "psMessage"}
	if StringInArray(l.Name, diyLogTypes) && GCB("diyLog."+l.Name) == false {
		return
	}
	switch l.Type {
	case "Debug":
		glog.Cat(l.Name).Debug(l.Info)
	case "Warning":
		glog.Cat(l.Name).Warning(l.Info)
	case "Error":
		glog.Cat(l.Name).Error(l.Info)
	default:
		glog.Cat(l.Name).Info(l.Info)
	}
}

func StringInArray(s string, d []string) bool {
	for _, v := range d {
		if s == v {
			return true
		}
	}
	return false
}
func InArrayInt(s interface{}, d []int) bool {
	for _, v := range d {
		if gconv.Int(s) == v {
			return true
		}
	}
	return false
}
func IntInArray(s int, d []int) bool {
	for _, v := range d {
		if s == v {
			return true
		}
	}
	return false
}
func InArrayFloat(s float64, d []float64) bool {
	for _, v := range d {
		if s == v {
			return true
		}
	}
	return false
}

//读取配置信息
//返回 string
func GCS(s ...string) string {
	//指定配置文件
	var fileName string
	if len(s) > 1 {
		fileName = "config/" + s[1]
	} else {
		fileName = "config/config.toml"
	}
	cfg := g.Config()
	cfg.SetFileName(fileName)
	return cfg.GetString(s[0])
}

//读取配置信息
//返回 int
func GCI(s ...string) int {
	//指定配置文件
	var fileName string
	if len(s) > 1 {
		fileName = "config/" + s[1]
	} else {
		fileName = "config/config.toml"
	}
	cfg := g.Config()
	cfg.SetFileName(fileName)

	return cfg.GetInt(s[0])
}

//读取配置信息
//返回 bool
func GCB(s ...string) bool {
	//指定配置文件
	var fileName string
	if len(s) > 1 {
		fileName = "config/" + s[1]
	} else {
		fileName = "config/config.toml"
	}
	cfg := g.Config()
	cfg.SetFileName(fileName)
	return cfg.GetBool(s[0])
}

//返回 []int
func GCIntS(s ...string) []int {
	//指定配置文件
	var fileName string
	if len(s) > 1 {
		fileName = "config/" + s[1]
	} else {
		fileName = "config/config.toml"
	}
	cfg := g.Config()
	cfg.SetFileName(fileName)
	return cfg.GetInts(s[0])
}

//返回 []string
func GCStringS(s ...string) []string {
	//指定配置文件
	var fileName string
	if len(s) > 1 {
		fileName = "config/" + s[1]
	} else {
		fileName = "config/config.toml"
	}
	cfg := g.Config()
	cfg.SetFileName(fileName)
	return cfg.GetStrings(s[0])
}

//生成token
func GetToken() string {
	// 获取当前时间的时间戳
	t := time.Now().Unix()
	// 生成一个MD5的哈希
	h := md5.New()
	// 将时间戳转换为byte，并写入哈希
	b := make([]byte, 8)
	binary.BigEndian.PutUint64(b, uint64(t))
	h.Write([]byte(b))
	//字节流转化为16进制的字符串
	return hex.EncodeToString(h.Sum(nil))
}

//hmac_sha1
func HMacSha1(s, k string) string {
	//hmac ,use sha1
	key := []byte(k)
	mac := hmac.New(sha1.New, key)
	mac.Write([]byte(s))
	return fmt.Sprintf("%x", mac.Sum(nil))
}

//字符串hash值
func StringHash(s string) uint32 {
	v := crc32.ChecksumIEEE([]byte(s))
	if v > 0 {
		return v
	}
	// v == MinInt
	return 0
}

func Md5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

//生成uuid
func UUID() string {
	u, err := uuid.NewV4()
	if err != nil {
		return ""
	}
	return u.String()
}
